package utils

import (
    "authserver/global"
    "bytes"
    "compress/gzip"
    "crypto/md5"
    "encoding/hex"
    "encoding/json"
    "errors"
    "fmt"
    "io"
    "io/ioutil"
    "log"
    "math/rand"
    "net/http"
    "net/url"
    "strings"
    "time"
)

func MD5V(str []byte) string {
	h := md5.New()
	h.Write(str)
	return hex.EncodeToString(h.Sum(nil))
}

// @Title Http发送Get请求
// @Description 函数的详细描述
// @Author 赵伟 2020/11/27 10:22
// @Param
// @Return

func Get(actionUrl string, params map[string]string, headers map[string]string,cookies []*http.Cookie) (err error, resp string, header map[string]string) {
	//new request
	req, err := http.NewRequest("GET", actionUrl, nil)
	if err != nil {
		fmt.Println(err.Error())
		return errors.New("new request is fail "), "", header
	}
	//add params
	q := req.URL.Query()
	if params != nil {
		for key, val := range params {
			q.Add(key, val)
		}
		req.URL.RawQuery = q.Encode()
	}

	//add headers
	if headers != nil {
		for key, val := range headers {
			req.Header.Add(key, val)
		}
	}

    for _,v:=range cookies{
        req.AddCookie(v)
    }

    // 添加host
    req.Header.Add("Host",req.Host)

    //bs,_:=json.Marshal(&req.Header)
    //fmt.Println(string(bs))


    //proxyUrl,err:=url.Parse("http://127.0.0.1:8080")
    //if err!=nil{
    //    global.GVA_LOG.Error("proxy err ",err.Error())
    //    return
    //}

	client := &http.Client{
		Timeout: 5 * time.Second,
        CheckRedirect: func(req *http.Request, via []*http.Request) error {
            return http.ErrUseLastResponse
        },
        //Transport: &http.Transport{
        //    Proxy: http.ProxyURL(proxyUrl),
        //},
	}

	fmt.Println("Go GET URL :", req.URL.String())

	//发送请求
	res, err := client.Do(req)
	if err != nil {
		return err, "", header
	}
	defer res.Body.Close() //一定要关闭res.Body
	//读取body

    var resBody []byte
    encoding:=res.Header.Get("Content-Encoding")
    //global.GVA_LOG.Debug("resp encoding :",encoding)
    if encoding == "gzip" {
        // 创建gzip解压缩器
        gzipReader, err := gzip.NewReader(res.Body)
        if err != nil {
            return err, "", header
        }
        defer gzipReader.Close()

        // 读取解压缩后的数据
        resBody, err = io.ReadAll(gzipReader)
        if err != nil {
            return err, "", header
        }
    }else{
        // 读取body
        resBody, err = io.ReadAll(res.Body) //把  body 内容读入字符串 s
        if err != nil {
            return err, "", header
        }
    }


	cHeader := res.Header.Clone()
	header = make(map[string]string)
	for k := range cHeader {
		header[k] = cHeader.Get(k)
	}

    for _,v:=range res.Cookies(){
        header[v.Name] = v.Value
    }

    bs,_:=json.Marshal(&header)
    fmt.Println(string(bs))

	return nil, string(resBody), header
}



// @Title Http发送Get请求
// @Description 函数的详细描述
// @Author 赵伟 2020/11/27 10:22
// @Param
// @Return

func GetByte(actionUrl string, params map[string]string, headers map[string]string,cookies []*http.Cookie) (err error,bs []byte) {
    //new request
    req, err := http.NewRequest("GET", actionUrl, nil)
    if err != nil {
        fmt.Println(err.Error())
        return errors.New("new request is fail "), bs
    }
    //add params
    q := req.URL.Query()
    if params != nil {
        for key, val := range params {
            q.Add(key, val)
        }
        req.URL.RawQuery = q.Encode()
    }

    //add headers
    if headers != nil {
        for key, val := range headers {
            req.Header.Add(key, val)
        }
    }

    for _,v:=range cookies{
        req.AddCookie(v)
    }

    // 添加host
    req.Header.Add("Host",req.Host)

    //bs,_:=json.Marshal(&req.Header)
    //fmt.Println(string(bs))


    //proxyUrl,err:=url.Parse("http://127.0.0.1:8080")
    //if err!=nil{
    //    global.GVA_LOG.Error("proxy err ",err.Error())
    //    return
    //}

    client := &http.Client{
        Timeout: 3600 * time.Second,
        CheckRedirect: func(req *http.Request, via []*http.Request) error {
            return http.ErrUseLastResponse
        },
        //Transport: &http.Transport{
        //    Proxy: http.ProxyURL(proxyUrl),
        //},
    }

    fmt.Println("Go GET URL :", req.URL.String())

    //发送请求
    res, err := client.Do(req)
    if err != nil {
        return err, bs
    }
    defer res.Body.Close() //一定要关闭res.Body
    //读取body

    var resBody []byte
    encoding:=res.Header.Get("Content-Encoding")
    //global.GVA_LOG.Debug("resp encoding :",encoding)
    if encoding == "gzip" {
        // 创建gzip解压缩器
        gzipReader, err := gzip.NewReader(res.Body)
        if err != nil {
            return err, bs
        }
        defer gzipReader.Close()

        // 读取解压缩后的数据
        resBody, err = io.ReadAll(gzipReader)
        if err != nil {
            return err, bs
        }
    }else{
        // 读取body
        resBody, err = io.ReadAll(res.Body) //把  body 内容读入字符串 s
        if err != nil {
            return err, bs
        }
    }

    return nil, resBody
}


// @Title Http发送Post请求
// @Description 函数的详细描述
// @Author 赵伟 2020/11/27 10:23
// @Param
// @Return
//
func PostJSON(url string, bodyJson []byte, params map[string]string, headers map[string]string) ([]byte, error) {
    //add post body
    var req *http.Request

    req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyJson))
    if err != nil {
        global.GVA_LOG.Error(err.Error())
        return nil, errors.New("new request is fail: %v \n")
    }
    //add params
    q := req.URL.Query()
    if params != nil {
        for key, val := range params {
            q.Add(key, val)
        }
        req.URL.RawQuery = q.Encode()
    }
    //add headers
    if headers != nil {
        for key, val := range headers {
            req.Header.Add(key, val)
        }
    }

    //tr := &http.Transport{
    //    TLSClientConfig:    &tls.Config{InsecureSkipVerify: false},
    //}

    //http client
    client := &http.Client{Timeout: 30 * time.Minute}
    global.GVA_LOG.Info("Go POST URL :  " + req.URL.RequestURI())

    //发送请求
    res, err := client.Do(req)
    if err != nil {
        global.GVA_LOG.Error(err.Error())
        return nil, err
    }
    defer res.Body.Close() //一定要关闭res.Body
    //读取body
    resBody, err := ioutil.ReadAll(res.Body) //把  body 内容读入字符串 s
    if err != nil {
        global.GVA_LOG.Error(err.Error())
        return nil, err
    }

    return resBody, nil
}



// @Title Http发送Post请求
// @Description 函数的详细描述
// @Author 赵伟 2020/11/27 10:22
// @Param
// @Return

func PostForm(postAddress string, params map[string]string, headers map[string]string, postForm map[string]string) (err error, resp string) {
	//new request

	data := url.Values{}
	for k, v := range postForm {
		data.Set(k, v)
	}
	payLoad := strings.NewReader(data.Encode())

	req, err := http.NewRequest("POST", postAddress, payLoad)
	if err != nil {
		fmt.Println(err.Error())
		return err, ""
	}
	//add params
	q := req.URL.Query()
	if params != nil {
		for key, val := range params {
			q.Add(key, val)
		}
		req.URL.RawQuery = q.Encode()
	}

	if headers != nil {
		for key, val := range headers {
			req.Header.Add(key, val)
		}
	}

	req.Header.Add("host", req.URL.Host)

	//http client
	client := &http.Client{Timeout: 5 * time.Second}
	fmt.Println("Go POST URL :", req.URL.String())

	//发送请求
	res, err := client.Do(req)
	if err != nil {
		return err, ""
	}
	defer res.Body.Close() //一定要关闭res.Body

    encoding:=res.Header.Get("Content-Encoding")
    global.GVA_LOG.Debug("resp encoding :",encoding)
    if encoding == "gzip" {
        // 创建gzip解压缩器
        gzipReader, err := gzip.NewReader(res.Body)
        if err != nil {
            log.Fatal(err)
        }
        defer gzipReader.Close()

        // 读取解压缩后的数据
        deBody := io.LimitReader(gzipReader, 512)
        resBody, err := io.ReadAll(deBody)
        if err != nil {
            log.Fatal(err)
        }
        return nil, string(resBody)
    }else{
        // 读取body
        resBody, err := ioutil.ReadAll(res.Body) //把  body 内容读入字符串 s
        if err != nil {
            return err, ""
        }
        return nil, string(resBody)
    }
}



// 获取随机key
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"

func GetRandomKey(length int) string {
    b := make([]byte, length)
    for i := range b {
        b[i] = charset[rand.Intn(len(charset))]
    }
    return string(b)

}
